package hist.mobilprogramming.tictactoeapplication;

/**
 * Class that control the entire game sequence for start to termination.
 * Has track of rounds played during a game session.
 * @author godtltro
 *
 */
public class GameManager
{
	private RoundContainer _rounds;
	private int _gameType;
	private String[] _playerNames;
	private boolean _occupiedSquare;

	/**
	 * @param rounds Keep track of all rounds to play
	 * @param gameType Kind of game that is played
	 * @param playerNames List of playernames
	 */
	public GameManager(RoundContainer rounds, int gameType, String[] playerNames)
	{
		_rounds = rounds;
		_gameType = gameType;
		_playerNames = playerNames;
	}
	
	/**
	 * @return Game type for this game
	 */
	public int getGameType()
	{
		return _gameType;
	}
	
	/**
	 * Updates the round accounting in case of a game decision.  
	 * @param currentPlayer Actual player concerned for the update
	 * @param occupiedText Update is aborted if this variable is set
	 * @param gameStatus Status created from last play event. 
	 * @return Descriptive text as result of an update or not.
	 */
	public String update(Player currentPlayer, String occupiedText, GameStatus gameStatus)
	{
		String text = "";
		text = getOccupiedText(occupiedText, currentPlayer);
		if (text != "") return text;
				
		try
		{
			text = getWinnerText(currentPlayer, _playerNames, gameStatus);
			if (text != "") 
				return text;
			
			if(gameStatus == GameStatus.Draw)
			{
				_rounds.increaseCompleted();		
				
				if (_rounds.getCompleted() < _rounds.toPlay())
					return "Omgangen endte med uavgjort!";
				
				// Added
				text = getWinnerText(currentPlayer, _playerNames, gameStatus);
				if (text != "") 
					return text;
				
				if (_rounds.toPlay() == 1)
					return "Spillet endte med uavgjort!";
				
				return "Siste omgang og spillet endte med uavgjort!";
			}
		}
		catch (ApplicationException e)
		{
			e.printStackTrace();
			text = "Alle omganger er ferdig. Velg nytt spill fra meny.";
		}
		
		if (currentPlayer == Player.X)
			text = _playerNames[1];
		else
			text = _playerNames[0];
	
		return text  + " sin tur!";
	}
	
	private String getOccupiedText(String occupied, Player currentPlayer)
	{
		String text = "";
		_occupiedSquare = false;
		
		if (occupied != "")		
		{
			_occupiedSquare = true;
			if (currentPlayer == Player.X)
				text = _playerNames[0];
			else
				text = _playerNames[1];
			
			return text  + ", " + occupied;
		}
		return text;
	}

	private String getWinnerText(Player currentPlayer, String[] players, GameStatus gameStatus) throws ApplicationException
	{
		String text = "";
		
		if (gameStatus == GameStatus.WonByPlayerX || gameStatus == GameStatus.WonByPlayerO)
		{							 
			 if (gameStatus == GameStatus.WonByPlayerX)
			 {
				 _rounds.increaseCompleted(Player.X.ordinal());
				 text = players[0];
			 }
			 
			 if (gameStatus == GameStatus.WonByPlayerO)
			 {	 
				 _rounds.increaseCompleted(Player.O.ordinal());
				 text = players[1];
			 }
			 
			 String gameText = "spillet";
			 if (_rounds.getCompleted() < _rounds.toPlay())
				 gameText = "omgangen";
		
			String winText = getFinalWinnerOfAllRoundsText();
			if (winText != "") 
				return winText;
			
			// draw check
			if (_rounds.terminated() && _rounds.getWinnerId() == 0)
				return text + " vant siste omgang, men spillet ble uavgjort!";
			
			return text + " vant " + gameText + "!";
		}
		
		String winText = getFinalWinnerOfAllRoundsText();
		if (winText != "") 
			return winText;
		
		return text;
	}
	
	/**
	 * @return Returns text for final winner of entire game if last round is played.
	 * Returns empty string if game session is not completed
	 */
	public String getFinalWinnerOfAllRoundsText()
	{
		int winnerId = _rounds.getWinnerId();
		
		if (_rounds.terminated() && winnerId > 0)
		{
			int winner;
			if (winnerId == Player.X.ordinal())
				winner = Player.X.ordinal();
			else
				winner = Player.O.ordinal();
			
			if (_rounds.toPlay() > 1)
			{
				String result = _rounds.getWinResultText(winner) + " - " + _rounds.getLossResultText(winner);
				return _playerNames[winnerId - 1] + " har flest seirer og vant spillet! (" + result  + ")";
			}
			return _playerNames[winnerId - 1] + " vant spillet!";
		}
		return "";
	}

	/**
	 * @return Return number of rounds to play in defined game session.
	 */
	public int roundsToPlay()
	{
		return _rounds.toPlay();
	}

	/**
	 * @return Descriptive text for current round to play
	 */
	public String getPlayingRoundText()
	{
		return _rounds.getPlayingRoundText();
	}
	
	/**
	 * @return True if all rounds in game are completed
	 */
	public boolean roundsTerminated()
	{
		return _rounds.terminated();
	}
	
	
	/**
	 * @return Winner id for the player who has won most rounds.
	 * Retruns 0 if no winner. 
	 */
	public int roundsWinnerId()
	{
		return _rounds.getWinnerId();
	}

	/**
	 * @return Number of rounds completed during game progress
	 */
	public int numOfRoundsCompleted()
	{
		return _rounds.getCompleted();
	}

	/**
	 * @param Player
	 * @return Get formated result for rounds played by given player
	 */
	public String getRoundsResultText(Player player)
	{
		return _rounds.getResultText(player.ordinal());
	}

	/**
	 * @return True when last update record an already taken square  
	 */
	public boolean occupiedSqaure()
	{
		return _occupiedSquare;
	}

}
